如何查看mysql里面的锁(详细)

您所在的位置:网站首页 mysql 查看被锁表 如何查看mysql里面的锁(详细)

如何查看mysql里面的锁(详细)

2024-07-13 00:43| 来源: 网络整理| 查看: 265

通过查询表统计信息查看

information_schema库下相关事务表和锁相关信息表介绍 innodb_trx 存储了当前正在执行的事务信息 trx_id:事务ID。 trx_state:事务状态,有以下几种状态:RUNNING、LOCK WAIT、ROLLING BACK 和 COMMITTING。 trx_started:事务开始时间。 trx_requested_lock_id:事务当前正在等待锁的标识,可以和 INNODB_LOCKS 表 JOIN 以得到更多详细信息。 trx_wait_started:事务开始等待的时间。 trx_mysql_thread_id:事务线程 ID,可以和 PROCESSLIST 表 JOIN。 trx_tables_locked:表示该事务目前加了多少个表级锁。 trx_lock_structs:表示该事务生成了多少个内存中的锁结构。 trx_lock_memory_bytes:事务锁住的内存大小,单位为 BYTES。 trx_rows_locked:表示该事务目前加了多少个行级锁。 innodb_locks 记录了锁信息 如果一个事务想要获取到某个锁但未获取到,则记录该锁信息 如果一个事务获取到了某个锁,但是这个锁阻塞了别的事务,则记录该锁信息 但是无法通过该表查询到谁被阻塞,谁持有未释放。 lock_id:锁 ID。 lock_trx_id:拥有锁的事务 ID。可以和 INNODB_TRX 表 JOIN 得到事务的详细信息。 lock_mode:锁的模式。 lock_type:锁的类型。RECORD 代表行级锁,TABLE 代表表级锁。 lock_table:被锁定的或者包含锁定记录的表的名称。 innodb_lock_waits 表明每个阻塞的事务是因为获取不到哪个事务持有的锁而被阻塞 requesting_trx_id:–获取不到锁而被阻塞的事务id(等待方) requested_lock_id:-- 请求锁ID ,事务所等待的锁定的 ID。可以和 INNODB_LOCKS 表 JOIN。 blocking_trx_id: --获取到别的事务需要的锁而阻塞其事务的事务id(当前持有方,待释放) blocking_lock_id: --这一事务的锁的 ID,该事务阻塞了另一事务的运行。可以和 INNODB_LOCKS 表 JOIN。 processlist id:标识ID。这与在SHOW PROCESSLIST语句的Id列、Performance Schema threads表的PROCESSLIST_ID列中显示的值类型相同,并由CONNECTION_ID()函数返回 user:发出该语句的mysql用户。 host:发出该语句的客户机的主机名(系统用户除外,没有主机)。 db:默认数据库。 command:线程正在执行的命令的类型。 time:线程处于当前状态的时间(以秒为单位)。 state:指示线程正在执行的操作、事件或状态。 info:线程正在执行的语句,如果没有执行任何语句,则为NULL。 如何借助这几张表来定位到有行锁等待

(1)查看当前有无锁等待

mysql> show status like ‘innodb_row_lock%’;

在这里插入图片描述 (2)查看哪个事务在等待(被阻塞了)

mysql> select * from information_schema.INNODB_TRX WHERE trx_state='LOCK WAIT'\G trx_state 表示该事务处于锁等待状态。 trx_query : 当前被阻塞的操作是select * from actor where actor_id=1 for update。 从trx_mysql_thread_id和trx_id可以看到这里查到当前被阻塞的事务的: 线程ID是 971,注意说的是线程id

事务ID是3934 在这里插入图片描述 (3)查询该事务被哪个事务给阻塞了 从innodb_trx获取到被阻塞的trx_id是3934,阻塞该事务的事务id是3933

mysql> SELECT * FROM performance_schema.threads WHERE processlist_id=970\G

在这里插入图片描述 (4)根据trx_id,从innodb_trx表可查询到trx_mysql_thread_id线程id为970

mysql> select * from information_schema.innodb_trx where trx_id=3933 \G

在这里插入图片描述 (5)根据线程id,查询表拿到thread_id为995

mysql> SELECT * FROM performance_schema.threads WHERE processlist_id=970\G

在这里插入图片描述 (6)根据thread_id,查询当前锁源的sql 在这里插入图片描述

整个流程如下: (1)首先查询是否有锁,根据锁查到被锁的trx_id (2)根据被锁的trx_id可以查到锁源的trx_id (3)根据锁源的trx_id查到trx_mysql_thread_id (4)再根据trx_mysql_thread_id查到thread_id (5)最后,用thread_id查找到锁源的sql

此外,第一步发现锁的方式,也可直接获取到锁源trx_id和被锁trx_id 在这里插入图片描述 但是这种方法在mysql8.0已经被移除,介绍另外一张表

sys.innodb_lock_waits 表

locked_table : 哪张表出现的等待

waiting_trx_id: 等待的事务(与上个视图trx_id 对应)

waiting_pid : 等待的线程号(与上个视图trx_mysql_thread_id)

blocking_trx_id : 锁源的事务ID

blocking_pid : 锁源的线程号

mysql> select * from sys.innodb_lock_waits\G 在这里插入图片描述 获取到锁源的blocking_pid 976(=processlist表的id),根据此id找到thread_id,再根据thread_id找到对应的sql 在这里插入图片描述 总结:

两种找到锁源SQL步骤是一样的

锁源的事务trx_id -->pnformaction_schema.processlist表的线程id–>performance_schema.threads表的thread_id–>performance_schema.events_statements_current 或performance_schema.events_statements_history查看sql 注:下面所指的id含义相同 information_schema.innodb_trx(trx_mysql_thread_id) information_schema.processlist(id) sys.innodb_lock_waits(waiting_pid,blocking_pid) sys.sys.innodb_lock_waits的应用 1)查看锁等待相关的(阻塞线程、被阻塞线程信息及相关用户、IP、PORT、locked_type锁类型) SELECT locked_table, locked_index, locked_type, blocking_pid, concat(T2.USER,'@',T2.HOST) AS "blocking(user@ip:port)", blocking_lock_mode, blocking_trx_rows_modified, waiting_pid, concat(T3.USER,'@',T3.HOST) AS "waiting(user@ip:port)", waiting_lock_mode, waiting_trx_rows_modified, wait_age_secs, waiting_query FROM sys.x$innodb_lock_waits T1 LEFT JOIN INFORMATION_SCHEMA.processlist T2 ON T1.blocking_pid=T2.ID LEFT JOIN INFORMATION_SCHEMA.processlist T3 ON T3.ID=T1.waiting_pid;

在这里插入图片描述 2)等待的持续时间(单位秒>20s)

SELECT trx_mysql_thread_id AS PROCESSLIST_ID, NOW(), TRX_STARTED, TO_SECONDS(now())-TO_SECONDS(trx_started) AS TRX_LAST_TIME , USER, HOST, DB, TRX_QUERY FROM INFORMATION_SCHEMA.INNODB_TRX trx JOIN sys.innodb_lock_waits lw ON trx.trx_mysql_thread_id=lw.waiting_pid JOIN INFORMATION_SCHEMA.processlist pcl ON trx.trx_mysql_thread_id=pcl.id WHERE trx_mysql_thread_id != connection_id() AND TO_SECONDS(now())-TO_SECONDS(trx_started) >= 20 ; show engine innodb status 将锁信息打印出来 mysql> set global innodb_status_output_locks =ON; 执行如下sql,fisrt_name上有普通二级索引 begin; select * from actor where first_name >'A' and first_name


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3